//
//  QRCodeViewController.swift
//  CLWeiBo
//
//  Created by 程雷 on 15/6/29.
//  Copyright © 2015年 程雷. All rights reserved.
//

import UIKit
import AVFoundation

class QRCodeViewController: UIViewController ,UITabBarDelegate,AVCaptureMetadataOutputObjectsDelegate{
    
    
    @IBOutlet weak var tabBar: UITabBar!
    
    // 扫描容器的高度约束
    @IBOutlet weak var heightConstraint: NSLayoutConstraint!
    // 扫描容器的宽度约束
    @IBOutlet weak var widthConstraint: NSLayoutConstraint!
    // 冲击波的顶部约束
    @IBOutlet weak var topConstraint: NSLayoutConstraint!
// 冲击波
    @IBOutlet weak var scanImage: UIImageView!
    // 扫描结果
    @IBOutlet weak var resultLabel: UILabel!
    
    //关闭
    
    @IBAction func close(sender: AnyObject) {
        
        dismissViewControllerAnimated(true, completion: nil)
    }

    // 显示我的名片
    @IBAction func showMyCard(sender: AnyObject) {
        
        navigationController?.pushViewController(QRCodeMyCardViewController(), animated: true)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // 默认选中第一项
        tabBar.selectedItem = tabBar.items![0]
        //设置二维码扫描环境
        setupSession()
        setupLayers()
    }
    
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        //开始动画
        startAnimation()
        //开始扫描
        startScan()
    }

   
    //开始动画
    func startAnimation()
    {
        topConstraint.constant = -heightConstraint.constant
        self.view.layoutIfNeeded()
        
        UIView.animateWithDuration(2.0) { () -> Void in
            //重复次数需要放在北部
            UIView.setAnimationRepeatCount(MAXFLOAT)
            
            // 添加了修改标记
            
            self.topConstraint.constant = self.heightConstraint.constant
            
            self.view.layoutIfNeeded()
            
        }
    }
    
    // MARK: ---TabBar 代理方法
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
        
        print(item.tag)
        
        //调整高度
        heightConstraint.constant = widthConstraint.constant * (item.tag == 1 ? 0.5 : 1)
        //停止动画
        scanImage.layer.removeAllAnimations()
        
        //重新开始动画
        
        startAnimation()
    }
    ///  开始扫描
    func startScan(){
        session.startRunning()
    }
    /// 设置图层
    private func setupLayers()
    {
        //设置绘图图层
        drawLayer.frame = view.bounds
        view.layer.insertSublayer(drawLayer, atIndex: 0)
        //预览图层
        previewLayer.frame = view.bounds
        // 设置图层填充模式
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        //将图层添加到当前图层
        view.layer.insertSublayer(previewLayer, atIndex: 0)
    }
    ///  设置会话
    private func setupSession(){
        // 1.判断能否添加移动设备
        if !session.canAddInput(inputDevice)
        {
            print("无法添加输入设备")
            return
        }
        // 2.判断能否添加输出数据
        if !session.canAddOutput(outputData)
        {
            print("无法添加输入设备")
            return
        }
        // 3. 添加设备
        session.addInput(inputDevice)
        print("前\(outputData.availableMetadataObjectTypes)")
        session.addOutput(outputData)
        // 只有添加到 session 之后，输出数据的数据类型才可用
        print("后\(outputData.availableMetadataObjectTypes)")
        
        // 4.设置检测数据类型，检测所有支持的数据格式
        outputData.metadataObjectTypes = outputData.availableMetadataObjectTypes
        // 5.设置数据代理
        outputData.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
    }

    // MARK --- AVCaptureMetadataOutputObjectsDelegate
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        
        // 清空图层
        clearDrawLayer()
        for object in metadataObjects
        {
            // 判断识别对象类型
            if object is AVMetadataMachineReadableCodeObject
            {
                // 转换数据类型
                let codeObject = previewLayer.transformedMetadataObjectForMetadataObject(object as! AVMetadataObject) as! AVMetadataMachineReadableCodeObject
                
                drawCorners(codeObject)
                //接收扫描结果
                resultLabel.text = codeObject.stringValue
            }
        }
    }
    // 清空绘图图层
    private func clearDrawLayer()
    {
        // 如果没有子图层直接返回
        
        if drawLayer.sublayers == nil
        {
            return
        }
        
        for subLayer in drawLayer.sublayers!
        {
            subLayer.removeFromSuperlayer()
        }
    }
    
    private func drawCorners(codeObject:AVMetadataMachineReadableCodeObject)
    {
        // 判断数组是否为空，如果为空就直接返回
        if codeObject.corners .isEmpty
        {
            return
        }
        print(codeObject)
        // 可以做动画绘图，专门在图层中绘画
        let layer = CAShapeLayer()
        layer.lineWidth = 4
        layer.strokeColor = UIColor.greenColor().CGColor
        layer.fillColor = UIColor.clearColor().CGColor
        layer.path = createPath(codeObject.corners).CGPath
        layer.path = UIBezierPath(rect: CGRect(x: 100, y: 100, width: 200, height: 200)).CGPath
        drawLayer.addSublayer(layer)
        
    }
    
    private func createPath(corners:NSArray) -> UIBezierPath
    {
        let path = UIBezierPath()
        //定义 point  -> UnsafeMutablePointer var
        
        var point = CGPoint()
        var index = 0
        
        //拿到第 0 个点
        CGPointMakeWithDictionaryRepresentation(corners[index++] as! CFDictionary, &point)
        // 移动到 第 0 个点
        
        path.moveToPoint(point)
        
        //遍历剩余的点
        while index < corners.count
        {
            CGPointMakeWithDictionaryRepresentation(corners[index++] as! CFDictionary, &point)
            //添加路线
            path.addLineToPoint(point)
        }
        
        // 关闭路径
        path.closePath()
        return path
    }
    
// MARK --- 懒加载－－－
    //绘图图层
    lazy var drawLayer:CALayer = CALayer()
    // 预览图层，依赖于session
    lazy var previewLayer:AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session:self.session)
    // 懒加载
    lazy var session:AVCaptureSession = AVCaptureSession()
    // 输入设备
    lazy var inputDevice:AVCaptureDeviceInput? = {
        // 取摄像头设备
        let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        do{
            return try AVCaptureDeviceInput(device: device)
        }
        catch{
            print(error)
            return nil
        }
    }()
    //输出设备
    
    lazy var outputData:AVCaptureMetadataOutput =  AVCaptureMetadataOutput()
    
}
